package com.kuang.exam.modules.sys.lesson.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kuang.exam.core.api.dto.PagingReqDTO;
import com.kuang.exam.core.exception.ServiceException;
import com.kuang.exam.core.utils.BeanMapper;
import com.kuang.exam.core.utils.StringUtils;
import com.kuang.exam.core.utils.passwd.PassHandler;
import com.kuang.exam.core.utils.passwd.PassInfo;
import com.kuang.exam.modules.sys.depart.entity.SysDepart;
import com.kuang.exam.modules.sys.depart.service.SysDepartService;
import com.kuang.exam.modules.sys.lesson.dto.UserLessonDTO;
import com.kuang.exam.modules.sys.lesson.dto.export.StudentsExportDTO;
import com.kuang.exam.modules.sys.lesson.dto.response.LessonStudentsDTO;
import com.kuang.exam.modules.sys.lesson.entity.SysLesson;
import com.kuang.exam.modules.sys.lesson.entity.SysUserLesson;
import com.kuang.exam.modules.sys.lesson.mapper.SysUserLessonMapper;
import com.kuang.exam.modules.sys.lesson.service.SysLessonService;
import com.kuang.exam.modules.sys.lesson.service.SysUserLessonService;
import com.kuang.exam.modules.sys.user.entity.SysUser;
import com.kuang.exam.modules.sys.user.service.SysUserRoleService;
import com.kuang.exam.modules.sys.user.service.SysUserService;
import com.kuang.exam.modules.user.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 用户课程信息业务实现类
 * </p>
 */
@Service
public class SysUserLessonServiceImpl extends ServiceImpl<SysUserLessonMapper, SysUserLesson> implements SysUserLessonService {


    @Autowired
    private SysUserLessonService userLessonService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysDepartService departService;

    @Autowired
    private SysLessonService lessonService;

    @Autowired
    private SysUserRoleService userRoleService;

    @Override
    public void removeByLessonId(List<String> lessonIds) {
        QueryWrapper<SysUserLesson> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(SysUserLesson::getLessonId, lessonIds);
        this.remove(wrapper);
    }

    @Override
    public void removeByUserId(List<String> userIds) {
        QueryWrapper<SysUserLesson> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(SysUserLesson::getUserId, userIds);
        this.remove(wrapper);
    }

    @Override
    public IPage<UserLessonDTO> paging(PagingReqDTO<UserLessonDTO> reqDTO) {
        //创建分页对象
        Page page = new Page(reqDTO.getCurrent(), reqDTO.getSize());
        String userId = UserUtils.getUserId();
        IPage<UserLessonDTO> pageData = baseMapper.paging(page, userId, reqDTO.getParams());
        pageData.getRecords().forEach(userLessonDTO -> {
            userLessonDTO.setStudentNum(this.calcStudNum(userLessonDTO.getLessonId(), userLessonDTO.getTeacherId()));
        });
        return pageData;
    }

    @Override
    public IPage<LessonStudentsDTO> pagingStudents(PagingReqDTO<UserLessonDTO> reqDTO) {

        IPage<SysUserLesson> page = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
        //查询条件
        QueryWrapper<SysUserLesson> wrapper = new QueryWrapper<>();

        UserLessonDTO params = reqDTO.getParams();

        if (params != null) {
            if (!StringUtils.isBlank(params.getLessonId())) {
                wrapper.lambda().eq(SysUserLesson::getLessonId, params.getLessonId());
            }

            if (!StringUtils.isBlank(params.getTeacherId())) {
                wrapper.lambda().eq(SysUserLesson::getTeacherId, params.getTeacherId());
            }
        }


        IPage<SysUserLesson> pageData = this.page(page, wrapper);
        IPage<LessonStudentsDTO> result = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
        List<LessonStudentsDTO> list = new ArrayList<>();
        pageData.getRecords().forEach(sysUserLesson -> {
            if (!sysUserLesson.getUserId().equals(sysUserLesson.getTeacherId())) {   // 排除老师
                SysUser user = userService.getById(sysUserLesson.getUserId());
                SysDepart depart = departService.getById(user.getDepartId());
                LessonStudentsDTO dto = new LessonStudentsDTO();
                BeanMapper.copy(sysUserLesson, dto);
                dto.setStudentNum(user.getUserName());
                dto.setStudentName(user.getRealName());
                dto.setStudentDept(depart == null ? "" : depart.getDeptName());
                list.add(dto);
            }
        });
        result.setRecords(list);
        return result;
    }

    @Override
    public List<UserLessonDTO> listByUserId() {
        String userId = UserUtils.getUserId();
        return baseMapper.listByUserId(userId);
    }

    @Override
    public List<String> listByLessonId(String lessonId) {
        List<String> teacherIds = new ArrayList<>();
        QueryWrapper<SysUserLesson> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUserLesson::getLessonId, lessonId);
        List<SysUserLesson> userLessonList = this.list(wrapper);
        userLessonList.forEach(userLesson -> {
            if (userLesson.getUserId().equals(userLesson.getTeacherId())) {  // 老师
                teacherIds.add(userLesson.getUserId());
            }
        });
        return teacherIds;
    }

    @Override
    public Integer calcStudNum(String lessonId, String teacherId) {
        QueryWrapper<SysUserLesson> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysUserLesson::getLessonId, lessonId)
                .eq(SysUserLesson::getTeacherId, teacherId);
        int count = userLessonService.count(wrapper);
        return count - 1;       // -1为学生的数量
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importExcel(List<StudentsExportDTO> dtoList) {
        // 约定第三行开始导入
        int line = 3;
        StringBuilder sb = new StringBuilder();

        if (CollectionUtils.isEmpty(dtoList)) {
            throw new ServiceException(1, "您导入的数据似乎是一个空表格！");
        }

        // 系统中不存在的学生，列表入库
        List<SysUser> userList = new ArrayList<>(dtoList.size());
        // 学生选课信息列表
        List<SysUserLesson> userLessonList = new ArrayList<>(dtoList.size());

        String lessonId = "";
        String teacherId = "";
        for (StudentsExportDTO dto : dtoList) {
            SysUserLesson userLesson = new SysUserLesson();
            // 处理课程
            if (!StringUtils.isBlank(dto.getLessonName())) {     //课程名不为空
                SysLesson lesson = lessonService.getByName(dto.getLessonName());
                if (lesson == null) {
                    sb.append("第").append(line).append("行，课程名不存在<br>");
                } else {
                    lessonId = lesson.getId();
                    userLesson.setLessonId(lessonId);
                }
            } else {
                userLesson.setLessonId(lessonId);
            }
            // 处理老师
            if (!StringUtils.isBlank(dto.getTeacher())) {     //老师名不为空
                //判断老师是否存在
                SysUser teacher = userService.getByUserName(dto.getTeacher());
                if (teacher == null) {
                    sb.append("第").append(line).append("行，老师用户名不存在<br>");
                } else {
                    teacherId = teacher.getId();
                    // 查找课程下的所有老师，判断课程和老师是否匹配
                    List<String> teacherIds = this.listByLessonId(lessonId);
                    if (!teacherIds.contains(teacherId)) {
                        sb.append("第").append(line).append("行，该老师未教授该课程<br>");
                    }
                    userLesson.setTeacherId(teacherId);
                }
            } else {
                userLesson.setTeacherId(teacherId);
            }
            // 处理学生
            if (StringUtils.isBlank(dto.getStudentNum()) || StringUtils.isBlank(dto.getStudentName()) || StringUtils.isBlank(dto.getStudentDept())) {
                sb.append("第").append(line).append("行，学生学号、姓名和班级不能为空<br>");
            } else {
                SysUser student = userService.getByUserName(dto.getStudentNum());
                SysDepart depart = departService.getByName(dto.getStudentDept());
                if (depart == null){
                    sb.append("第").append(line).append("行，班级不存在<br>");
                }
                // 库中不存在的学生
                if (student == null) {
                    SysUser sysUser = new SysUser();
                    sysUser.setId(IdWorker.getIdStr());
                    sysUser.setUserName(dto.getStudentNum());
                    sysUser.setRealName(dto.getStudentName());
                    sysUser.setDepartId(depart == null ? "" :depart.getId());
                    PassInfo passInfo = PassHandler.buildPassword("123456");    //默认密码
                    sysUser.setPassword(passInfo.getPassword());
                    sysUser.setSalt(passInfo.getSalt());
                    sysUser.setRoleIds("student");
                    userRoleService.saveRoles(sysUser.getId(), Collections.singletonList("student"));
                    userList.add(sysUser);
                    userLesson.setUserId(sysUser.getId());
                }else {
                    userLesson.setUserId(student.getId());
                }
            }
            userLessonList.add(userLesson);
            line++;
        }

        // 存在错误
        if (!"".equals(sb.toString())) {
            throw new ServiceException(1, sb.toString());
        }

        // 入库
        this.saveBatch(userLessonList);
        userService.saveBatch(userList);
    }
}
